package com.cskaoyan.javase.oop1._13block._2building;

/**
 * 总结目前成员变量的赋值
 * 总结一下到目前为止，创建对象过程中可能碰到的结构的执行顺序：
 * new对象过程中，各种结构的执行顺序：
 *      1.对象结构存在后就进行默认初始化，所有成员变量都具有默认值后，再开始其余赋值操作
 *          JVM创建对象,只要对象的结构存在,其中的成员变量就会具有默认值
 *          在程序员能够看到或者能够控制的成员变量赋值和访问时,成员变量已经具有了默认值.
 *      2.找到new对象的那个构造器
 *          如果它的首行显式地调用了另一个构造器
 *          （注：显式调用构造器目前指的是this调用自身构造器，其它场景这里先不考虑，比如super，因为你没学）
 *      那么程序会先跳转到那个构造器，但是不会立刻执行，而是：
 *      按照类中构造代码块和显式赋值的代码书写顺序，从上到下执行其中的代码，执行完毕后：
 *          跳转回this语句要指示执行的构造器，执行其中的代码，然后：
 *          跳转回new对象构造器，执行完毕后，创建对象结束。
 *          (这个跳转的过程按照方法栈帧的先进后出实现)
 *注：整个过程中，构造代码块和显式赋值的代码只会执行一次，不会执行多次！！
 * 如果这个构造器的首行有this显式调用别的构造器,那么构造代码块和显式赋值的代码就不会加进去了
 * (这是为了保证它们只被执行一次)
 * 如果它的首行没有显式调用另一个构造器
 * 那么会先从上到下执行构造代码块和显式赋值代码，执行完毕后：
 * 跳转回new对象构造器，执行完毕后，创建对象结束。
 * 注：整个过程中，构造代码块和显式赋值的代码只会执行一次，不会执行多次！！
 * 以上总结，没有引入继承的概念，并不全面，我们会在继承中补全它。
 *
 * @since 15:17
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo2 {
    public static void main(String[] args) {
        Star s = new Star(500, 50);
        System.out.println(s.age);
        System.out.println(s.salary);
    }
}

class Star {
    {
        salary = 200;
        System.out.println("代码上面的构造代码块");
    }

    double salary = 100;
    int age = 40;

    {
        salary = 300;
        age = 38;
        System.out.println("代码下面的构造代码块");
    }

    public Star(double salary) {
        this();
        this.salary = salary;
        System.out.println("我是单参的构造器");
    }

    public Star(double salary, int age) {
        this(salary);
        this.age = age;
        System.out.println("我是双参的构造器");
    }

    public Star() {
        // this(100,100);
        System.out.println("我是无参构造器!");
    }
}